using System;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;



namespace Open.Data.Persistence
{
    public class Columns: Collection<IColumn>
    {
        //Constructors
        public Columns()
        {
        }

        public Columns(Type type, string names)
        {
            string[] fields = names.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
            foreach (String field in fields)
            {
                string name = field.Replace(" ", "");
                PropertyInfo prop = type.GetProperty(name);
                if (prop == null) throw new PersistenceException(string.Format("Property {0} not found for type {1}.", name, type.FullName));
                Add(new Column(prop));
            }
        }

        public Columns(Type type, string[] names)
        {
            foreach (String field in names)
            {
                Add(new Column(type.GetProperty(field)));
            }
        }

        public Columns(PropertyInfo[] properties)
        {
            foreach (PropertyInfo prop in properties)
            {
                Add(new Column(prop));
            }
        }

        //Methods

        public IColumn[] ToArray()
        {
            IColumn[] destinationArray = new IColumn[Count];
            this.CopyTo(destinationArray, 0);
            return destinationArray;
        }

        public virtual void AppendHashCode(StringBuilder builder)
        {   
            //Use the property info from each field rather than the hash for speed
            foreach (IColumn field in this)
            {
                PropertyInfo prop = field.PropertyInfo;
                
                if (typeof(IView).IsAssignableFrom(prop.ReflectedType))
                {
                    CacheItem cache = Provider.Instance.ReflectionCache.Lookup(prop.ReflectedType);
                    prop = cache.GetOriginalProperty(prop);
                }

                builder.Append(prop.ToString());
            }
        }

        public PropertyInfo[] ToPropertyInfoArray()
        {
            List<PropertyInfo> list = new List<PropertyInfo>(this.Count);

            foreach (IColumn column in this)
            {
                list.Add(column.PropertyInfo);
            }
            return list.ToArray();
        }
    }
}